home *** CD-ROM | disk | FTP | other *** search
/ PC Format (UK) 124 / pcfcd124-a.iso / Trial Software / BlitzBasic / Rift2001-05-16 / Rift2 / tutorial2c-complete.bb < prev    next >
Encoding:
Text File  |  2001-05-16  |  35.5 KB  |  671 lines

  1. AppTitle "Celestial Rift - Version 1.1 (C)2001 Myke P" ;what this program will be called in MICROSOFT WINDOWS.
  2.  
  3. ;This makes two CONSTants. These are values which will NOT change at any point in the program, so we set their values now.
  4. Const SCREEN_WIDTH = 800
  5. Const SCREEN_HEIGHT = 600
  6. ;This is the code which tells Blitz what Display Resolution to use on the Graphics Card. The "GRAPHICS" command should always be placed before you do
  7. ;*anything* image-related in your program
  8. Graphics SCREEN_WIDTH,SCREEN_HEIGHT,0,1    ;start the graphics mode at SCREEN_WIDTH by SCREEN_HEIGHT, let Blitz choose the depth (,0) and run full screen (,1)
  9.  
  10. ;more program CONSTants..
  11. Const GAME_AREA_X = 50000    ;these two set the size of the map. You *should* keep them the same, 'cos the radar is square
  12. Const GAME_AREA_Y = 50000    ;but technically, you can change the values to anything you like! ;)
  13. ;the following constants are keyboard "SCAN" codes. Every key on the keyboard has a number. You can get the full list in your Blitz manual.
  14. Const KEY_CLOCKWISE = 25    ;(p)    
  15. Const KEY_ANTICWISE = 24    ;(o)
  16. Const KEY_SPEEDUP = 16        ;(q)
  17. Const KEY_SPEEDDOWN = 30    ;(a)
  18. Const KEY_FIRE = 57            ;(Space)
  19. Const KEY_HYPER = 2            ;(1)
  20. Const KEY_BOOST = 50        ;(m)
  21. Const KEY_CLOAK = 46        ;(c)
  22. Const KEY_QUIT = 1            ;(Escape)
  23. Const KEY_PAUSE = 7            ;(Number 6 on the main keyboard)
  24. Const KEY_DEBUG = 59        ;(F1)
  25. Const KEY_SAVESCREEN = 88    ;(F12)
  26. ;the following constants affect the way the game plays. Feel free to mess with the values..
  27. Const INCR_ROTATE# = 5                ;.. but DON'T touch this, otherwise the game will crash (I only drew the animation frames for 5 degree intervals!)
  28. Const INCR_SPEED# = 0.5
  29. Const INCR_SLOW# = 0.125
  30. Const INCR_BOOSTERS_UP# = 0.025
  31. Const INCR_BOOSTERS_DOWN# = .75
  32. Const INCR_CLOAK_UP#= 0.0125
  33. Const INCR_CLOAK_DOWN# = .25 
  34. Const SPEED_MAX = 25
  35. Const SPEED_MIN = -5
  36.  
  37. ;set up changable variables for game/menu (with initial values, if you like - i.e.: you could just as soon as set them later!)
  38. Global FLAG_GAMEON = 1
  39. Global FLAG_PAUSE
  40. Global FLAG_SAVESCREEN = 0
  41. Global FLAG_DEBUG = 0
  42. Global FLAG_GAMESTARTER
  43. Global PLAYER_SHIELD#
  44. Global PLAYER_BOOSTERS#
  45. Global PLAYER_CLOAK#
  46. Global PLAYER_JUMPS
  47. Global PLAYER_SPEED#
  48. Global PLAYER_ANGLE#
  49. Global PLAYER_X#
  50. Global PLAYER_Y#
  51. Global PLAYER_SCORE
  52. Global HI_SCORE
  53.  
  54. Global timer
  55. Global frames
  56. Global starson
  57. Global game_pause_frame
  58. Global game_accept_pause
  59. Global game_pause_stat
  60. Global hypercount#        ;a "#" symbol after the variable name means it can hold a FLOATING POINT number, i.e.: 190.1234
  61. Global pausecount        ;without the "#" symbol, the variable is, by default, an INTEGER (Whole) number, i.e.: 190
  62. Global cloakon#            ;use the symbols when you are *sure* that you want it to hold specific types of data:
  63. Global frame1            ;# - floating point
  64. Global frame2            ;% - integer (whole number)
  65. Global frame3            ;$ - string (text, i.e.: "MYKE 12345"
  66. Global frame4            ;
  67. Global frame5
  68. Global frame6
  69. Global frame7
  70. Global frame8
  71. Global tempstr$
  72.  
  73. timer = CreateTimer(50) ;create a timer set at 50ms (game speed) - play with this to see how you can increase or decrease the speed of the game.
  74.                         ;this should be set at a speed which will look near enough the same on *every* PC it will be played on.
  75.                         ;My PC (a 733MHz PIII with an nVidia GeForce card) will handle upwards of 150 frames per second, quite happily
  76.                         ;but 'lesser' machines will not. 50, therefore, is quite sensible For a game of this nature, who's minimum system spec
  77.                         ;will be something like a PII 300MHz machine (i.e.: Blitz Basic's minimum spec!)
  78.  
  79. ;NOTE: there's no need to organise your variable declarations, as I have here, into sections. They can appear in any order you like, before the main program begins.
  80. ;I just do this, 'cos it looks right professional! :))))
  81.  
  82. ;picture/animation (and related) variables
  83. Dim game_stars(5)            ;these 3 are ARRAYS. An array is automatically Global, but requires the Keyword (Yellow bit) DIM instead. This means "Dimension".
  84. Dim game_icons(4)            ;the arrays have single dimensions (imagine one straight line of boxes, each that can contain a single variable) 0 to.. (the number in brackets)
  85. Global game_icon_dot
  86. Global game_player
  87. Global game_player_frame
  88. Global game_player_dot
  89. Global game_bullet_player
  90. Global game_gameover
  91. Global game_paused
  92.  
  93. ;Types are like Structures in C. You have a "Type" called whatever. Then you can make multiple versions of the type. Each version of the Type has the same properties, i.e.:
  94. ;a FISH (the Type) has EYES, MOUTH, SCALES And FINS (it's properties) - ALL FISH have these properties.
  95. ;a DOG (the Type) has EYES, MOUTH, FUR and TAIL (it's properties) - ALL DOGS have these properties (look like this.)
  96. Type stars                        ;create "Type" for parallex stars
  97.     Field depth,x#,y#            ;each star has a depth, x and y position
  98. End Type
  99.  
  100. Type icons                        ;same for icons
  101.     Field x#,y#,style,frame#
  102. End Type
  103.  
  104. ;this code makes 4 'objects' in a "Type" called "ICONS".
  105. For i = 1 To 4                    ;do this 1, 2, 3, 4 times
  106.     icon.icons = New icons        ;create a new icon
  107.     icon\style = i                ;the icon style for each new icon is equal to the increment of i (i.e.: 1, 2, 3 or 4!)
  108.     icon\frame = Int(Rnd(0,5))    ;create a random frame number between 0 and 5 for each new icon
  109. Next
  110.  
  111. menustars = SCREEN_HEIGHT/3 ;generate a number of stars, so that they look dense enough on all test resolutions
  112. starson = 1 ;tells the program to show the stars (see later)
  113. For i=0 To menustars                    ;create <menustars> number of stars in the STARS type
  114.     star.stars=New stars                ;add a new star for each increment of i
  115. Next
  116.  
  117. ;this code loads the image numbers into an array called "game_ stars", which we DIMmed earlier. It has 6 containers (0,1,2,3,4,5) but I'm only using 1 to 5!
  118. ;an "image number" is what Blitz uses to reference graphics held in the Video Memory, i.e.:
  119. ;1. Image number 12 is a picture of a flower.
  120. ;2. Make a variable called "flower_pic" = 12
  121. ;3. Wherever Blitz is told to draw "flower_pic", reference image number 12 in the Video Memory.
  122. game_stars(1) = LoadImage("GfxRes/backg-star-1.bmp")    ;container (1) in "game_stars" holds the image number for this picture ("GfxRes/backg-star-1.bmp")
  123. game_stars(2) = LoadImage("GfxRes/backg-star-2.bmp")    ;etc..
  124. game_stars(3) = LoadImage("GfxRes/backg-star-3.bmp")
  125. game_stars(4) = LoadImage("GfxRes/backg-star-4.bmp")
  126. game_stars(5) = LoadImage("GfxRes/backg-star-5.bmp")
  127. For i = 1 To 5
  128.     MaskImage game_stars(i),255,0,255    ;mask the images for each star, so that MAGENTA (255,0,255) is the transparent colour
  129. Next
  130.  
  131. ;similarly, this code loads the image numbers into an array called "game_icons"
  132. ;however, these are images that contain the frames of an Animation, so a different Load command is used.
  133. game_icons(1) = LoadAnimImage("GfxRes/icon-boost.bmp",32,32,0,6)    ;LoadAnimImage has the same structure as LoadImage, with additional numbers after the picture filename
  134. game_icons(2) = LoadAnimImage("GfxRes/icon-shield.bmp",32,32,0,6)    ;these are: Frame Width (pixels), Frame Height (pixels), Starting Framenumber (usually 0)
  135. game_icons(3) = LoadAnimImage("GfxRes/icon-cloak.bmp",32,32,0,6)    ;and the Number of Frames in the Image (as *you* would count them (in this case 6)
  136. game_icons(4) = LoadAnimImage("GfxRes/icon-jump.bmp",32,32,0,6)        ;have a look at the file "icon-boost" in Paint Shop Pro and see for yourself the 6 frames of animation.
  137. For i = 1 To 4
  138.     MaskImage game_icons(i),255,0,255    ;mask the images for each icon, so that MAGENTA (255,0,255) is the transparent colour
  139. Next
  140.  
  141. ;notice in the following code, we're loading (and MASKING) graphics in exactly the same way as before, but into regular variables instead of arrays.
  142. ;this next bit is all animations
  143. game_player = LoadAnimImage("GfxRes/player-ship.bmp",80,80,0,72) ;load in the 'sprite' for the player ship
  144. MaskImage game_player,255,0,255 ;mask the images for the player ship, so that MAGENTA (255,0,255) is the transparent colour
  145. ;these are all plain single-frame pictures
  146. ;game piccies
  147. game_gameover = LoadImage("GfxRes/game-gameover.bmp")        ;the game over logo, which I tend to see a lot of.. :(
  148. game_paused = LoadImage("GfxRes/game-paused.bmp")            ;the paused logo
  149. game_player_dot = LoadImage("GfxRes/player-radardot.bmp")    ;radar dots for the player and bonus icons respectively
  150. game_icon_dot = LoadImage("GfxRes/icon-radardot.bmp")
  151. MaskImage game_gameover,255,0,255
  152. MaskImage game_paused,255,0,255
  153.  
  154. ;Right! That's it, we've set up *everything* we're going to need from outside the program. Let's start up the game_loop function..
  155. game_loop()
  156.  
  157. ;this function keeps the game loop going.. It starts playing tunes and sets a couple of variables. 
  158. ;Then it goes into a never ending loop which carries out a sequence of checks and function calls, until such time as we want to stop it!
  159. Function game_loop()
  160.     FLAG_GAMEON = 1 ;tells the program that the game is running.
  161.     game_initialise()     ;calls a function called "game_initialise()" (which is next in the code) which
  162.                         ;just gives the player full energy and a score of 0 etc..)
  163.     Repeat        ;as with the menu, we want to cycle though the process of updating/drawing forever, until such time as the game has ended.
  164.         If FLAG_GAMEON = 1 Then        ;.. so, if FLAG_GAMEON is 1, then "do" the following.
  165.             game_loop_update()                                ;call the game_loop_update() function
  166.         Else
  167.             FlushKeys                
  168.             End                    ;if FLAG_GAMEON isn't 1, we End the program
  169.         End If
  170.     Forever
  171. End Function
  172.  
  173. ;As described a minute ago, this function sets up the game variables as they should be
  174. ;at the start of every game, i.e.: Player Shields are full, the score is 0 etc..
  175. Function game_initialise()
  176.     FLAG_DEBUG = 1                    
  177.     FLAG_GAMESTARTER = 1
  178.     hypercount = 102
  179.     FLAG_PAUSE = 0
  180.     PLAYER_SCORE = 0
  181.     PLAYER_TIME = 0
  182.     PLAYER_ANGLE = 0
  183.     PLAYER_SPEED = 0
  184.     PLAYER_SHIELD = 192            ;the width of the game_level image is 192. Rather than working out a percentage of 100, it's much
  185.     PLAYER_BOOSTERS = 192        ;easier to use the width of the image on such BAR type displays.
  186.     PLAYER_CLOAK = 192            
  187.     PLAYER_JUMPS = 5
  188.     game_player_randomize()            ;calls a function that randomizes a player's position on the map
  189.     game_stars_randomize()            ;calls a function that randomizes the star positions
  190.  
  191.     ;this next bit is the first time you'll have seen a TYPE cycle.
  192.     ;Just like a normal "For i = 0 to 20" loop, this goes through each Version of a type
  193.     ;and set's it's properties. (i.e.: That FISH type has a SCALES property. Here we tell it that this particular Fish's Scales are GOLD!)
  194.     For icon.icons = Each icons
  195.         icon\x = Rnd(0,GAME_AREA_X)        ;for each of the 4 icons on the play area at any one point, we need a random x and y position.
  196.         icon\y = Rnd(0,GAME_AREA_Y)
  197.     Next
  198. End Function
  199.  
  200. ;once again, like it's menu equivalent, "game_loop_update()" is a function which analyses player input, working out all the new
  201. ;coordinate positions and anything else which needs deciding before updating the screen display.
  202. Function game_loop_update()
  203.     frames = WaitTimer(timer)
  204.     For i = 1 To frames
  205.         If KeyDown(KEY_PAUSE)                                    ;checks to see if the user has pressed the "PAUSE" key
  206.             FlushKeys
  207.             If game_accept_pause = 1                            ;the "game_accept_pause" variable is used in the same way as "menu_accept_quit" earlier.
  208.                                                                 ;because we're using SCANCODES, the program will register a number of qualifying cases where
  209.                                                                 ;when this check is performed, the key is still held down (at 50 frames per second, if the user
  210.                                                                 ;held down the key for half a second, the KEYDOWN function would fire around 25 times!)
  211.                                                                 
  212.                 If FLAG_PAUSE = 0 Then                            ;If FLAG_PAUSE is 0 then..
  213.                     FLAG_PAUSE = 1                                ;make FLAG_PAUSE = 1
  214.                     game_accept_pause = 0                        ;don't accept any more "PAUSE" button presses until "game_accept_pause" is set back to 1
  215.                     game_pause_frame = 1                        ;make "game_pause_frame" = 1 which, similarly to "menu_frame" earlier will enable the flashing of "PAUSED".
  216.                 Else
  217.                     FLAG_PAUSE = 0                                ;If FLAG_PAUSE isn't 0 (the game was paused) then..
  218.                     game_accept_pause = 0                        ;do exactly the same, but set FLAG_PAUSE to 0.
  219.                     game_pause_frame = 1
  220.                 End If
  221.             End If
  222.         End If
  223.         If KeyDown(KEY_SAVESCREEN)        ;If the "SCREENSAVE" button is pressed..
  224.             FlushKeys                    ;this functions exactly the same as in menu_loop_update()
  225.             FLAG_SAVESCREEN = 1
  226.         End If
  227.         If KeyDown(KEY_QUIT)        ;If the "QUIT" button is pressed..
  228.             FlushKeys
  229.             hypercount = 0
  230.             cloakon = 0
  231.             FLAG_GAMEON=0             ;set FLAG_GAMEON to equal 0. Back in the "game_loop()" function, this will cause the code to jump back to the menu.
  232.         End If
  233.  
  234.         If FLAG_PAUSE = 0 Then                            ;this is really easy! If the game is paused then *don't* do any of the following code. No values will change,
  235.                                                         ;hence nothing will move on the screen when it comes to updating it later! :)
  236.                                                         
  237.                 If KeyDown(KEY_HYPER)                    ;if the "HYPER" key is pressed then..
  238.                     If PLAYER_JUMPS > 0 Then
  239.                         If hypercount = 0 Then                ;(if "hypercount" is 0, then we're not already in the middle of a HyperJump, so let's set things off!)
  240.                             hypercount = 1                        ;by setting "hypercount" to 1, we'll set off a chain of events later on..
  241.                             PLAYER_JUMPS = PLAYER_JUMPS - 1        ;subtract the number of Jumps a player has left by 1
  242.                             If PLAYER_JUMPS <= 0 Then            ;if the number of jumps left is 0 or less, then the above subtraction will make it "-1", so..
  243.                                 PLAYER_JUMPS = 0                ;put it back to 0.
  244.                             End If
  245.                         End If
  246.                     End If
  247.                     FlushKeys
  248.                 End If
  249.                 If hypercount = 0 Then                        ;as long as we're not in the middle of a hyperjump, do the following..
  250.                 
  251.                     If KeyDown(KEY_CLOAK)            ;if the CLOAK key is pressed then
  252.                     
  253.                         If PLAYER_CLOAK > 2 Then        ;if the player has enough (2 points of) PLAYER_CLOAK left, then..
  254.                             cloakon = cloakon + 1                                    ;the cloakon value is incremented so that later on, we can do the flickering effect
  255.                             PLAYER_CLOAK = PLAYER_CLOAK - INCR_CLOAK_DOWN            ;subtract some PLAYER_CLOAK ability at a rate of "INCR_CLOAK_DOWN"
  256.                             
  257.                         Else                            ;if the player doesn't have enough PLAYER_CLOAK left then
  258.                             cloakon = 0                        ;reset the "cloakon" value to 0
  259.                             PLAYER_CLOAK = 0                ;Keep the PLAYER_CLOAK value at 0, so that it doesn't build up...
  260.                         End If
  261.                         FlushKeys
  262.                     Else                            ;if the CLOAK key isn't pressed then
  263.                         cloakon = 0                            ;reset the "cloakon" value to 0
  264.                         If PLAYER_CLOAK < 192                                ;if the player has less than the top value (192 points) of PLAYER_CLOAK then..
  265.                             PLAYER_CLOAK = PLAYER_CLOAK + INCR_CLOAK_UP            ;Slowly build up the PLAYER_CLOAK value.
  266.                         Else
  267.                             PLAYER_CLOAK = 192                                ;otherwise cap the PLAYER_CLOAK value at 192 points.
  268.                         End If
  269.                         FlushKeys
  270.                     End If
  271.                     If KeyDown(KEY_BOOST)                            ;the BOOST key works in exactly the same way as the CLOAK key
  272.                         If PLAYER_BOOSTERS > 2 Then
  273.                             If PLAYER_SPEED < (SPEED_MAX*3) Then
  274.                                 PLAYER_SPEED = PLAYER_SPEED + (INCR_SPEED * 3)
  275.                             End If
  276.                             PLAYER_BOOSTERS = PLAYER_BOOSTERS - INCR_BOOSTERS_DOWN
  277.                         Else
  278.                             PLAYER_BOOSTERS = 0
  279.                         End If
  280.                         FlushKeys
  281.                     Else
  282.                         If PLAYER_BOOSTERS < 192
  283.                             PLAYER_BOOSTERS = PLAYER_BOOSTERS + INCR_BOOSTERS_UP
  284.                         Else
  285.                             PLAYER_BOOSTERS = 192
  286.                         End If
  287.                         FlushKeys
  288.                     End If
  289.                     If KeyDown(KEY_CLOCKWISE)                            ;if "CLOCKWISE" key is pressed then..
  290.                         PLAYER_ANGLE = PLAYER_ANGLE + INCR_ROTATE            ;Add "INCR_ROTATE" degrees to the current PLAYER_ANGLE
  291.                         FlushKeys
  292.                         If PLAYER_ANGLE >= 360 Then                            ;if the PLAYER_ANGLE is 360, then reset it to 0.
  293.                             PLAYER_ANGLE = PLAYER_ANGLE - 360
  294.                         End If
  295.                     End If
  296.                     If KeyDown(KEY_ANTICWISE)                            ;exactly the same, but Subtract "INCR_ROTATE" from the player angle and
  297.                         PLAYER_ANGLE = PLAYER_ANGLE - INCR_ROTATE        ;reset it to (for example) 355, if the angle is -5.
  298.                         FlushKeys
  299.                         If PLAYER_ANGLE < 0 Then
  300.                             PLAYER_ANGLE = PLAYER_ANGLE + 360
  301.                         End If
  302.                     End If
  303.                     If KeyDown(KEY_SPEEDUP) Then                        ;if the "SPEEDUP" key is pressed.
  304.                         If PLAYER_SPEED < SPEED_MAX                            ;as long as the player speed is less than the maximum speed (SPEED_MAX), then
  305.                             PLAYER_SPEED = PLAYER_SPEED + INCR_SPEED        ;Add "INCR_SPEED" to the player's speed value
  306.                             FlushKeys
  307.                         Else
  308.                             PLAYER_SPEED = PLAYER_SPEED - INCR_SLOW            ;if the PLAYER_SPEED is not less than the maximum speed then take "INCR_SLOW" off of it!
  309.                             FlushKeys
  310.                         End If
  311.                     Else                                                ;if the key isn't being pressed, then..
  312.                         If PLAYER_SPEED > 0 Then                            ;as long as the player speed is greater than 0, then take "INCR_SLOW" off the current value
  313.                             PLAYER_SPEED = PLAYER_SPEED - INCR_SLOW            ;(this is an easy "No power" decelaration for the space ship)
  314.                         End If
  315.                         FlushKeys
  316.                     End If
  317.                     If KeyDown(KEY_SPEEDDOWN)                            ;exactly the same thing, but with the ship's thrusters in reverse! :)
  318.                         If PLAYER_SPEED > SPEED_MIN
  319.                             PLAYER_SPEED = PLAYER_SPEED - INCR_SPEED
  320.                             FlushKeys
  321.                         Else
  322.                             PLAYER_SPEED = SPEED_MIN
  323.                             FlushKeys
  324.                         End If
  325.                     Else
  326.                         If PLAYER_SPEED < 0 Then
  327.                             PLAYER_SPEED = PLAYER_SPEED + INCR_SLOW
  328.                         End If
  329.                     End If
  330.                 End If    ;end of the "If we're not in the middle of a hyperjump" IF statement
  331.                 
  332.                 ;this next peice of code updates the player position on the map, relative to it's Speed and Angle and it's last position
  333.                 PLAYER_X = PLAYER_X + (PLAYER_SPEED*(Sin(PLAYER_ANGLE)/2))
  334.                 PLAYER_Y = PLAYER_Y - (PLAYER_SPEED*(Cos(PLAYER_ANGLE)/2))
  335.                 If PLAYER_X < 0 Then                        ;if the PLAYER_X value is less than 0, then wrap your position around the map
  336.                     PLAYER_X = (PLAYER_X + GAME_AREA_X)        ;by adding the GAME_AREA_X value to the negative value, i.e.: -5 becomes 19995 on a 20000 X pixel map.
  337.                 End If
  338.                 If PLAYER_X > GAME_AREA_X Then                ;the same in reverse, i.e. 20004 becomes 4 on the same map.
  339.                     PLAYER_X = (PLAYER_X - GAME_AREA_X)
  340.                 End If
  341.                 If PLAYER_Y < 0 Then                        ;and now the same for the Y direction
  342.                     PLAYER_Y = (PLAYER_Y + GAME_AREA_Y)
  343.                 End If
  344.                 If PLAYER_Y > GAME_AREA_Y Then
  345.                     PLAYER_Y = (PLAYER_Y - GAME_AREA_Y)
  346.                 End If
  347.     
  348.             For icon.icons=Each icons                ;the "icons" don't move from their randomly set x,y position, so all we need to do for them is
  349.                 icon\frame = icon\frame+.5            ;update their animation frame number. There are 6 frames, and we're incrementing at 0.5 frames per update.
  350.                 If Int(icon\frame) = 6 Then            ;in real terms, this means we'll be updating the frame number every 2 updates.
  351.                     icon\frame = 0                    ;Because the icon animations are simple 0 to 5 cycling animations, when the frame number reaches 6, we flip it back to 0
  352.                 End If                                ;to start the sequence again.
  353.             Next
  354.             
  355.             ;this next bit of code creates the "simple but effective" Hyperjump event, based entirely on the value of "hypercount" being set to 1, earlier in the code.
  356.             If hypercount > 0 Then
  357.                 If (hypercount/2 = Int(hypercount/2)) Then    ;this line says "If the value of 'hypercount' is an EVEN number"
  358.                                                             ;because 5 (an odd number) would be 2.5 when devided by 2, but conversion to an INTeger gives 3.
  359.                                                             ;2.5 does NOT equal 3!
  360.                     ;all of this simply rotates the HyperJump ships in different offset directions
  361.                     ;the only difference is, we're not bothering with degrees here, just animation frame numbers, i.e.: 355 degrees is frame 71 (i.e.: 355/5 degree increment)
  362.                     frame1 = frame1 + 3
  363.                     frame2 = frame2 - 3
  364.                     frame3 = frame1 + 9
  365.                     frame4 = frame2 - 9
  366.                     frame5 = frame1 + 36
  367.                     frame6 = frame2 - 36
  368.                     frame7 = frame1 + 54
  369.                     frame8 = frame2 - 54
  370.                     If frame1 >=72 Then
  371.                         frame1 = frame1-72
  372.                     End If
  373.                     If frame1 < 0 Then
  374.                         frame1 = frame1+72
  375.                     End If
  376.                     If frame2 >=72 Then
  377.                         frame2 = frame2-72
  378.                     End If
  379.                     If frame2 < 0 Then
  380.                         frame2 = frame2+72
  381.                     End If
  382.                     If frame3 >=72 Then
  383.                         frame3 = frame3-72
  384.                     End If
  385.                     If frame3 < 0 Then
  386.                         frame3 = frame3+72
  387.                     End If
  388.                     If frame4 >=72 Then
  389.                         frame4 = frame4-72
  390.                     End If
  391.                     If frame4 < 0 Then
  392.                         frame4 = frame4+72
  393.                     End If
  394.                     If frame5 >=72 Then
  395.                         frame5 = frame5-72
  396.                     End If
  397.                     If frame5 < 0 Then
  398.                         frame5 = frame5+72
  399.                     End If
  400.                     If frame6 >=72 Then
  401.                         frame6 = frame6-72
  402.                     End If
  403.                     If frame6 < 0 Then
  404.                         frame6 = frame6+72
  405.                     End If
  406.                     If frame7 >=72 Then
  407.                         frame7 = frame7-72
  408.                     End If
  409.                     If frame7 < 0 Then
  410.                         frame7 = frame7+72
  411.                     End If
  412.                     If frame8 >=72 Then
  413.                         frame8 = frame8-72
  414.                     End If
  415.                     If frame8 < 0 Then
  416.                         frame8 = frame8+72
  417.                     End If
  418.                 End If    ;end of the "if hypercount is EVEN" IF statement
  419.                 
  420.                 ;this bit increases the value of "hypercount" until it reaches 200
  421.                 hypercount = hypercount + 1
  422.                 If hypercount > 0 And hypercount <= 102 Then    ;between 0 and 102, the player speed increases
  423.                     PLAYER_SPEED = PLAYER_SPEED + 2
  424.                 ElseIf hypercount > 102 And hypercount < 200 Then    ;between 102 and 200, the player speed decreases (but only if FLAG_GAMESTARTER is 0)
  425.                     If FLAG_GAMESTARTER = 0 Then                    ;this is because when the game starts, the player speed is 0, but we've faked being in
  426.                         PLAYER_SPEED = PLAYER_SPEED - 2                ;the middle of a hyperjump. Without this FLAG, the player ship would start each game
  427.                     End If                                            ;travelling at about -90 speed backwards, which would just be weird! :)
  428.                 End If
  429.                 If hypercount = 100 Then
  430.                     game_stars_randomize()    ;half way through the Hyperjump sequence, the "game_stars_randomize()" function is called, which changes all the star positions    
  431.                                             ;and depths, to give the impression we've moved to a completely different part of space
  432.                 End If
  433.                 If hypercount/10 = Int(hypercount/10) Then
  434.                     game_player_randomize()        ;every 10 updates, the function "game_player_randomize()" is called. This randomly jumps the player around the map
  435.                                                 ;and confuses the hell out of the bad guys! (well it will by next month's tutorial!!) ;))
  436.                 End If
  437.                 If hypercount = 200 Then        ;if the "hypercount" variable reaches 200, then stop the sequence and reset the value back to 0
  438.                     hypercount = 0
  439.                     FLAG_GAMESTARTER = 0        ;also, when the game first starts we were in the middle of a hyperjump. Resetting this FLAG back to 0 means that
  440.                                                 ;the next hyperjump sequence will decrease the speed after "hypercount" gets to 103
  441.                 End If
  442.             Else                            ;if we're not in the middle of a hyperjump event, then:
  443.                 frame1=game_player_frame-1    ;this bit is just for the DEBUG mode. It was designed to check that 360 degrees became 0 degrees and vice versa correctly
  444.                 frame2=game_player_frame+1
  445.                 If frame1 < 0 Then
  446.                     frame1 = frame1 + 72
  447.                 End If
  448.                 If frame2 >= 72 Then
  449.                     frame2 = frame2 - 72
  450.                 End If
  451.             End If    ;end of the "Are we in the middle of a Hyperjump" IF statement
  452.             
  453.             ;the parralex stars move relative to the player and is just the same "menustars" number of stars
  454.             ;scrolled at various speeds, wrapping around the screen.
  455.             ;it's a fairly cheap, but effective way of creating a nice illusion of speed!
  456.             If starson=1 Then                ;if, at the beginning of the program, you set "starson" to 0, the stars will disappear.
  457.                                             ;the game would also feel pretty bloody wierd.. hold on.. yep.. Absolutely mad! Try it! :)
  458.                 For star.stars=Each stars
  459.                     ;the following two lines move each version of the "stars" Type an x and y distance relative to the player's speed and angle
  460.                     ;with a devision relative to the depth of the star to make the smallest stars move slower than the biggest
  461.                     ;thus we have our parallex effect.
  462.                     
  463.                     ;it might be of interest to know that these two lines were based on the OLDSKOOL demo which comes with Blitz Basic
  464.                     ;and was the starting point for the whole CELESTIAL RIFT game concept! Thanks a lot, Mr Mikkel L°kke!! :)
  465.                     star\y=(star\y+PLAYER_SPEED*(Cos(360-PLAYER_ANGLE)/(6-star\depth+1)))
  466.                     star\x=(star\x+PLAYER_SPEED*(Sin(360-PLAYER_ANGLE)/(6-star\depth+1)))
  467.                     ;the maximum pixel width of for the biggest star image is 5 pixels
  468.                     ;the following IF statements wrap the stars around the screen border when they reach the extremities
  469.                     If star\x < -5 Then
  470.                         star\x = star\x + (SCREEN_WIDTH + 5)
  471.                     End If
  472.                     If star\x > SCREEN_WIDTH Then
  473.                         star\x = star\x - (SCREEN_WIDTH + 5)
  474.                     End If
  475.                     If star\y <= -5 Then
  476.                         star\y = star\y + (SCREEN_HEIGHT + 5)
  477.                     End If
  478.                     If star\y >= SCREEN_HEIGHT
  479.                         star\y = star\y - (SCREEN_HEIGHT + 5)
  480.                     End If
  481.                 Next
  482.             End If    ;end of the "are the stars going to be shown" IF statement
  483.  
  484.             PLAYER_SCORE = PLAYER_SCORE + 1        ;if the game is in progress, then increase the PLAYER_SCORE by 1 every screen update
  485.                                                     ;this acts as a kind of survival bonus for the more defensive player
  486.                 If PLAYER_SCORE >= HI_SCORE Then
  487.                     HI_SCORE = PLAYER_SCORE
  488.                 End If
  489.             
  490.         End If ;end of "IF FLAG_PAUSE = 0" IF Statement
  491.         
  492.         ;this flashes the "PAUSED" caption on and off when needs be!
  493.         game_pause_frame = game_pause_frame + 1
  494.         If game_pause_frame = 25 Then
  495.             game_pause_frame = 1
  496.             game_accept_pause = 1
  497.             If game_pause_stat = 1 Then
  498.                 game_pause_stat = 0
  499.             Else
  500.                 game_pause_stat = 1
  501.             End If
  502.         End If
  503.  
  504.     Next    ;end of the "for i = 1 to frames" FOR loop
  505.     
  506.     game_draw_update()    ;finally, draw all the pictures on the screen, based on their (possibly) new positions.
  507. End Function
  508.  
  509. ;this function draws the game graphics in their freshly calculated positions
  510. Function game_draw_update()
  511.     SetBuffer BackBuffer()    ;draw all of the following to the backbuffer
  512.     ClsColor 0,0,0            ;changes the CLearScreen colour to black (0,0,0)
  513.     Cls
  514.     If starson=1 Then        ;draw all of the stars using their correct pictures, at the correct x and y positions
  515.         For star.stars=Each stars ;(for each star in type 'stars' do the following..)
  516.             DrawImage game_stars(star\depth),star\x,star\y    ;using the depth property of "stars" as the Array position
  517.         Next
  518.     End If
  519.     
  520.         ;this FOR Type loop draws all the versions of "icons" at their screen-position - relative to the PLAYER coordinates
  521.         ;in the current animation frame. It also checks for the non-transparent areas of the ICON image touching the non-
  522.         ;transparent areas of the PLAYER image and updates the PLAYER's relavent energy-level values.
  523.         For icon.icons=Each icons
  524.         
  525.             ;this line draws the relavant icon image at coordinates "x" and "y" on (or off) the screen
  526.             ;the correct icon image is chosen using the "icons"'s style as it's array position
  527.             ;the x and y coordinates are worked out by subtracting the PLAYER's current position from the "icons"'s current position
  528.             ;notice that we're using the same style of "SCREEN_WIDTH\2 - Half the ImageWidth of the Image" idea from the
  529.             ;"menu_draw_update()" code?
  530.             DrawImage game_icons(icon\style), (((SCREEN_WIDTH/2)-ImageWidth(game_icons(icon\style))/2) - (PLAYER_X - icon\x)), (((SCREEN_HEIGHT/2)-ImageWidth(game_icons(icon\style))/2) - (PLAYER_Y - icon\y)),Int(icon\frame)
  531.  
  532.         Next    ;end of the "icons" FOR loop
  533.  
  534.     ;this section draws the frames of "animation" for the hyperjump, or - if we're not mid hyperjump - draws the regular player frames
  535.     ;the hyperjump bits look quite complecated, but it's just x and y positions that are changing in relation to the value of "hypercount"
  536.     If hypercount > 0 And hypercount < 100 Then
  537.         If hypercount/2 = Int(hypercount/2) Then        ;if the value of "hypercount" is EVEN then..
  538.                                                         ;draw these four pictures
  539.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-hypercount,frame2
  540.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+hypercount,frame4
  541.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+hypercount,frame6
  542.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-hypercount,frame8
  543.  
  544.         Else                                            ;otherwise, if the value of "hypercount" is ODD, then..
  545.                                                         ;draw these four pictures..
  546.                                                         ;this ODD/EVEN swapping results in our "flickery" effect, but you
  547.                                                         ;can see the distinct 4 pictures if you PAUSE the game in the middle of a jump!
  548.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(1.4*hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame7
  549.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(1.4*hypercount),frame5
  550.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(1.4*hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame3
  551.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(1.4*hypercount),frame1
  552.         End If
  553.     ElseIf hypercount >= 100 And hypercount < 200 Then    ;between 0 and 100, the 8 "ships" move outwards from the middle..
  554.                                                         ;after that, they converge back to the centre, using exactly the same code, but "200 - hypercount"
  555.                                                         ;instead of "hypercount". It's a cheap effect that didn't cost me any more Paint Shop Pro time
  556.                                                         ;and it looks quite cool! :)
  557.         If hypercount/2 = Int(hypercount/2) Then
  558.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(200-hypercount),frame2
  559.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(200-hypercount),frame4
  560.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(200-hypercount),frame6
  561.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(200-hypercount),frame8
  562.         Else
  563.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(1.4*(200-hypercount)),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame7
  564.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(1.4*(200-hypercount)),frame5
  565.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(1.4*(200-hypercount)),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame3
  566.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(1.4*(200-hypercount)),frame1
  567.         End If
  568.  
  569.     Else            ;if, on the other hand, we're not mid-hyperjump, then we'll just be drawing the normal player frames..
  570.     
  571.         ;checks to see that the angle we want to draw the frame for is 0 to 71 (as 360 degrees is the same as 0 degrees!)
  572.         game_player_frame = PLAYER_ANGLE/5
  573.         If game_player_frame = 72 Then
  574.             game_player_frame = 0
  575.         End If
  576.         
  577.         If cloakon = 0 Then        ;if the "cloaking device" is off, then draw the player every screen update..
  578.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,game_player_frame
  579.  
  580.         Else                    ;if the "cloaking device" is on, only draw the player when the "cloakon" number is EVEN..
  581.                                 ;this is our flickering effect used again..
  582.             If cloakon/2 = Int(cloakon/2) Then
  583.                 DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,game_player_frame
  584.             End If
  585.         End If
  586.     End If
  587.     
  588.     ;As we said before, the foremost pictures/displayed objects are drawn last in our Video collage.
  589.     Color 0,128,0
  590.     Text SCREEN_WIDTH-210,220,"SCORE: " + PLAYER_SCORE
  591.     Text SCREEN_WIDTH-210,240,"HISCR: " + HI_SCORE
  592.     Text SCREEN_WIDTH-210,260,"BOOST: " + Int(PLAYER_BOOSTERS)
  593.     Text SCREEN_WIDTH-210,280,"CLOAK: " + Int(PLAYER_CLOAK)
  594.     Text SCREEN_WIDTH-210,300,"JUMPS: " + PLAYER_JUMPS
  595.     Line SCREEN_WIDTH-210,3,SCREEN_WIDTH-10,3
  596.     Line SCREEN_WIDTH-210,213,SCREEN_WIDTH-10,213
  597.     Line SCREEN_WIDTH-210,3,SCREEN_WIDTH-210,213
  598.     Line SCREEN_WIDTH-10,3,SCREEN_WIDTH-10,213
  599.         ;notice that by using a calculated x coordinate "SCREEN_WIDTH - value" in conjunction with a fixed
  600.         ;y coordinate, we will have the HUD images at the same distance from the top right of the screen
  601.         ;in any Graphics resolution we choose -- PLUS I've made the radar border GREEN using the color command
  602.         
  603.     Color 255,0,255
  604.     
  605.     ;this next bit of code draws the coloured dots on the radar
  606.     ;by using their game map coordinates, at a ratio to the size of the radar box graphic
  607.     For icon.icons=Each icons
  608.         ;this draws each of the icons
  609.         DrawImage game_icon_dot,((SCREEN_WIDTH-211)+icon\x/(GAME_AREA_X/200)),((9)+icon\y/(GAME_AREA_Y/200))
  610.     Next
  611.     
  612.     ;this next bit draws the player's green dot on the radar
  613.     If hypercount = 0 And cloakon=0 Then    ;if both the "hypercount" and "cloakon" features are inactive (i.e.: normal play)
  614.         ;then permanently draw the player's radar dot
  615.         DrawImage game_player_dot,((SCREEN_WIDTH-211)+PLAYER_X/(GAME_AREA_X/200)),((9)+PLAYER_Y/(GAME_AREA_Y/200))
  616.  
  617.     ElseIf hypercount = 0 And (cloakon/2 = Int(cloakon/2)) Then
  618.         ;otherwise, if the cloakon value is EVEN, draw the dot (flickery effect again)
  619.         ;but if the hypercount value isn't 0 (we're in the middle of a hyperjump) then don't do this..
  620.         ;.. consequently, even though the player's position moves on the radar map during a hyperjump,
  621.         ;and it affects the enemies, don't show this to the user!
  622.         DrawImage game_player_dot,((SCREEN_WIDTH-211)+PLAYER_X/(GAME_AREA_X/200)),((9)+PLAYER_Y/(GAME_AREA_Y/200))
  623.     End If
  624.  
  625.     ;if the game is paused (FLAG_PAUSE = 1) then draw the image when "game_pause_stat" = 1
  626.     ;this gives us our flash on-off effect as used earlier in "menu_draw_update()"
  627.     
  628.     If FLAG_PAUSE = 1 And game_pause_stat = 1 Then
  629.         DrawImage game_paused,SCREEN_WIDTH/2-ImageWidth(game_paused)/2,SCREEN_HEIGHT-((SCREEN_HEIGHT-350)/2+ImageHeight(game_paused)/2)
  630.     End If
  631.     
  632.     ;the following text will only be printed on the screen while the "FLAG_DEBUG" variable is set to 1 (which for the purpose of this tutorial, we've left it at!)
  633.     If FLAG_DEBUG = 1 Then
  634.         ;the TEXT command writes a STRING of text onto the screen at the given coordinates in the currently set font
  635.         ;as I haven't used the LoadFont or SetFont commands, this will just be Blitz' default font.
  636.  
  637.         Color 255,255,255                                    ;just in case, set the colo(u)r of the text to WHITE (255, 255, 255)
  638.         Text 0,0,"PLAYER ANGLE = " + PLAYER_ANGLE                ;"Write the string 'PLAYER ANGLE = ' followed by the number held in PLAYER_ANGLE"
  639.         Text 0,20,"PLAYER SPEED = " + PLAYER_SPEED
  640.         Text 0,40,PLAYER_ANGLE + " / 5 = " + PLAYER_ANGLE/5
  641.         Text 0,60,"SHIPFRAME = " + game_player_frame
  642.         Text 0,80,"CO-ORDS = " + Int(PLAYER_X)
  643.         Text 140,80," , " 
  644.         Text 160,80,Int(PLAYER_Y)
  645.         Text 0,120, "SCORE = " + PLAYER_SCORE
  646.     End If
  647.     
  648.     ;just like in "menu_draw_update()", the user can press a key which just makes the value of "FLAG_SCREENSAVE" equal 1.
  649.     ;when the code gets to here, it saves out the named Buffer as a BMP picture.
  650.     If FLAG_SAVESCREEN=1 Then
  651.         SaveBuffer (BackBuffer(),"CRGameScreen.bmp")
  652.         FLAG_SAVESCREEN = 0
  653.     End If 
  654.     
  655.     Flip                    ;as before in "menu_draw_update()", FLIP everything we've just drawn on the backbuffer and show it on the frontbuffer, i.e.: your monitor!!
  656. End Function
  657.  
  658. ;a little function which randomizes the x and y coordinates of each version of the "stars" Type, plus it's "depth" property
  659. Function game_stars_randomize()
  660.     For star.stars=Each stars
  661.         star\x=Rnd(-5,SCREEN_WIDTH)            ;create random x and y positions for all the stars
  662.         star\y=Rnd(-5,SCREEN_HEIGHT)
  663.         star\depth=Rnd(1,5)                    ;the depth of the stars results in our sexy parallex effect
  664.     Next
  665. End Function
  666.  
  667. ;an even littler function which just gives us random x and y coordinates for the player.
  668. Function game_player_randomize()
  669.     PLAYER_X = Rand(0,GAME_AREA_X)
  670.     PLAYER_Y = Rand(0,GAME_AREA_Y)
  671. End Function